package com.bupt.service.common.impl;

import com.bupt.Factory.ProjectFactory;
import com.bupt.annotation.MParam;
import com.bupt.base.BaseDataSupport;
import com.bupt.basic.BasicNetWork;
import com.bupt.basic.IBasicNetWork;
import com.bupt.basic.Project;
import com.bupt.config.interceptor.thread.CurrentUserInfo;
import com.bupt.constants.InitConstants;
import com.bupt.dto.network.*;
import com.bupt.dto.sys.LoginUserDto;
import com.bupt.dto.sys.UserDto;
import com.bupt.exception.BaseException;
import com.bupt.service.common.LinkService;
import com.bupt.service.system.SysLoginService;
import com.bupt.utils.GenerateIDUtils;
import com.bupt.utils.LinkStatusString;
import com.bupt.utils.LocalVerify;
import com.bupt.utils.TypeString;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.math3.analysis.function.Add;
import org.springframework.stereotype.Service;
import sun.awt.image.ImageWatched;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.*;

@Service("linkService")
public class LinkServiceImpl implements LinkService {

    @Resource
    private CurrentUserInfo userInfo;

    //锁信息
    private static final Object lock = new Object(); // 锁信息
    private static final String successListKey = "successList"; // 成功的列表
    private static final String failListKey = "failList"; //失败的列表

    @Override
    public Object addFiberLink(UserDto userDto, String projectId, String fiberName, String code, String sourceId, String targetId,
                               Integer xxsl, String asfs, Double xxsh, long length, int year, int serviceLength, Integer fualtTime, Double aveAttenua) throws BaseException {

        // 校验参数的完成性
        LocalVerify.verifyStringIsNotNull(code, fiberName, sourceId, targetId, asfs);
        userDto = userInfo.getCurrentOptUser();
        synchronized (lock) {
            // 新创建链路
            BasicNetWork.BasicLink link = new BasicNetWork.FiberLink(GenerateIDUtils.generateIdStr(), "FIBER", code,
                    fiberName, fiberName, sourceId, null,targetId,null, false, year, userDto.getUId(),
                    userDto.getUserName(), new Date(), xxsl.longValue(), asfs, length, null, null,
                   xxsh, null, null, length, serviceLength, fualtTime, aveAttenua);
            // 请求添加链路操作
            Map<String, List<AddLinkDto>> resMap =
                    addLinksToBasicNetwork(userDto, projectId, Collections.singletonList(link), false);
            if (resMap.get(failListKey).size() != 0)
                throw new BaseException(resMap.get(failListKey).get(0).getReason());
            System.out.println(resMap.toString());
              return getFiberLinksList(userDto,projectId);
        }
    }

    @Override
    public Object deleteFiberLink(UserDto userDto, String projectId, String fiberId) throws BaseException {
        LocalVerify.verifyString(fiberId, "链路ID");
        LocalVerify.verifyStringIsNotNull(projectId);
        synchronized (lock) {
            if(removeLinkFromBasicNetwork(userDto, projectId,fiberId, "FIBER")){
                return getFiberLinksList(userDto,projectId);
            }else {
                throw new BaseException("删除fiber链路失败");
            }
        }
    }

    @Override
    public Object updateFiberLink(UserDto userDto, String projectId, String fiberLinkId, String fiberName, String code, Integer xxsl, long length, int year, int serviceLength, String asfs, Integer fualtTime, Double aveAttenua, Double xxsh) throws BaseException {
        // 校验参数的完成性
        LocalVerify.verifyStringIsNotNull(code, fiberName, asfs, fiberLinkId);
        synchronized (lock) {
            userDto = userInfo.getCurrentOptUser();
            // 创建更新对象
            BasicNetWork.BasicLink link = new BasicNetWork.FiberLink(fiberLinkId, "FIBER", code,
                    fiberName, fiberName, null, null,null,null, false, year, userDto.getUId(),
                    userDto.getUserName(), new Date(), xxsl.longValue(), asfs, length, null,
                    null, xxsh, null, null, length, serviceLength, fualtTime, aveAttenua);
            // 执行更新的操作
            if (updateLinkToBasicNetWork(userDto, projectId, link)) {
                return getFiberLinksList(userDto, projectId);
            } else {
                throw new BaseException("更新fiber链路失败");
            }
        }
    }

    private boolean updateLinkToBasicNetWork(UserDto userDto, String projectId,IBasicNetWork.BasicLink link)throws  BaseException {
        LocalVerify.verifyObject(link, link.getClass().getName());
        synchronized (lock) {
            Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
            // 获取网络中心库信息
            BasicNetWork basicNetWork =project.getBasicNetWork();
            // 设置其他的信息
            link.setUpdateId(userDto.getUId());
            link.setUpdateName(userDto.getUserName());
            link.setUpdateTime(new Date());
            // 更新链路的信息
            basicNetWork.updateLink(link);// # issue 抛出异常 就是无法更新的
            // 更新网络信息至项目中
            updateProject(project);
            // 返回信息
            return true;
        }
    }

    @Override
    public Object getFiberLinksList(UserDto userDto, String projectId) throws BaseException {
        Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
        BasicNetWork basicNetWork = project.getBasicNetWork();
        List<IBasicNetWork.BasicLink> fiberLinks =basicNetWork.getFiberLinks();
        List<FiberLinkDto> fiberLinkDtos=new ArrayList<>();
        for (IBasicNetWork.BasicLink fiberLink : fiberLinks) {
            IBasicNetWork.FiberLink f = (IBasicNetWork.FiberLink) fiberLink;
            List<Node> node = getNode(fiberLink,project);
            FiberLinkDto fiberLinkDto = new FiberLinkDto(f.getId(), f.getName(), f.getCode(), node.get(0), node.get(1), f.getYear(), f.getServiceLength(),
                    f.getLength(), f.getXxsl(), f.getAsfs(), f.getFaultTime(), f.getAveAttenua(), f.getXxsh());
            fiberLinkDtos.add(fiberLinkDto);
        }
        return fiberLinkDtos;
    }

   List<Node> getNode(IBasicNetWork.BasicLink  link,Project project) {
       List<Node> nodeList = new ArrayList<>();
       IBasicNetWork.BasicNode fromNode = project.searchNodeById(link.getNodeHead());
       IBasicNetWork.BasicNode toNode = project.searchNodeById(link.getNodeTail());
       Node node1 = new Node(fromNode.getNodeId(), fromNode.getName(), fromNode.getPointX(), fromNode.getPointY());
       Node node2 = new Node(toNode.getNodeId(), toNode.getName(), toNode.getPointX(), toNode.getPointY());
       nodeList.add(node1);
       nodeList.add(node2);
       return nodeList;
   }


    @Override
    public Object addWdmLink(UserDto userDto, String projectId, String linkName, String code, String sourceId, String targetId, long size, long length, int year, String rate) throws BaseException {
        // 校验参数的完成性
        LocalVerify.verifyStringIsNotNull(code, linkName, sourceId, targetId);
        userDto = userInfo.getCurrentOptUser();
        synchronized (lock) {
            // 新建立路径
            BasicNetWork.BasicLink link = new BasicNetWork.WdmLink(GenerateIDUtils.generateIdStr(), "WDM", code,
                    linkName, linkName, sourceId,null, targetId,null, false, year, userDto.getUId(),
                    userDto.getUserName(), new Date(), size, rate, "FIBER", length);
            Map<String, List<AddLinkDto>> resMap =
                    this.addLinksToBasicNetwork(userDto,projectId, Collections.singletonList(link), false);
            if (resMap.get(failListKey).size() != 0)
                throw new BaseException(resMap.get(failListKey).get(0).getReason());
            return getWdmLinksList(userDto,projectId);
        }
    }

    @Override
    public Object getWdmLinksList(UserDto userDto, String projectId) throws BaseException {
        Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
        BasicNetWork basicNetWork = project.getBasicNetWork();
        List<IBasicNetWork.BasicLink> wdmLinks = basicNetWork.getWdmLinks();
        List<WdmLinkDto> wdmLinkDtos=new ArrayList<>();
        for (IBasicNetWork.BasicLink wdmLink : wdmLinks) {
            IBasicNetWork.WdmLink w = (IBasicNetWork.WdmLink) wdmLink;
            List<Node> node = getNode(wdmLink,project);
            WdmLinkDto wdmLinkDto = new WdmLinkDto(w.getId(), w.getName(), w.getCode(), node.get(0), node.get(1), w.getLength(), w.getYear(), w.getSize(), w.getRateStr(),w.getBaseLinkIds(),w.getBaseLinkNames());
            wdmLinkDtos.add(wdmLinkDto);
        }
        return wdmLinkDtos;
    }

    @Override
    public Object updateWdmLink(UserDto userDto, String projectId, String linkId, String code, String linkName, int year, long size, String rate, long length) throws BaseException {
        LocalVerify.verifyStringIsNotNull(code, linkName, rate, linkId);
        userDto = userInfo.getCurrentOptUser();
        synchronized (lock) {
            // 新建立路径
            BasicNetWork.BasicLink link = new BasicNetWork.WdmLink(linkId, "WDM", code,
                    linkName, linkName, null,null, null,null, false, year, userDto.getUId(),
                    userDto.getUserName(), new Date(), size, rate, "FIBER", length);
            // 执行更新的操作
            if (updateLinkToBasicNetWork(userDto, projectId, link)) {
                return getWdmLinksList(userDto,projectId);
            }else {
                throw new BaseException("更新wdm链路失败");
            }
        }
    }

    @Override
    public Object deleteWdmLink(UserDto userDto, String projectId, String linkId) throws BaseException {
        LocalVerify.verifyString(linkId, "链路ID");
        LocalVerify.verifyStringIsNotNull(projectId);
        synchronized (lock) {
           if(removeLinkFromBasicNetwork(userDto, projectId,linkId, "WDM")){
               return getWdmLinksList(userDto,projectId);
           }else {
               throw new BaseException("删除wdm链路失败");
           }
        }
    }

    public boolean removeLinkFromBasicNetwork(UserDto userDto,String projectId, String linkId, String layer) throws BaseException {
        LocalVerify.verifyString(linkId, "链路的ID");
        LocalVerify.verifyString(layer, "层次信息");
        synchronized (lock) {
            Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
            BasicNetWork basicNetWork = project.getBasicNetWork();
            basicNetWork.removeLink(project,linkId, BasicNetWork.LayerEnum.getLayerEnum(layer));
            // 更新网络信息
            updateProject(project);
            return true;
        }
    }

    @Override
    public Object addOtnLink(UserDto userDto, String projectId, String linkName, String code, String sourceId, String targetId, int year, String loadOnlayer, String rate, long length) throws BaseException {
        LocalVerify.verifyStringIsNotNull(code, linkName, targetId,sourceId, loadOnlayer);
        synchronized (lock) {
            userDto = userInfo.getCurrentOptUser();
            // OTN 的链路
            BasicNetWork.BasicLink link = new BasicNetWork.OtnLink(GenerateIDUtils.generateIdStr(), "OTN", code,
                    linkName, linkName, sourceId,null, targetId, null,false, year, userDto.getUId(),
                    userDto.getUserName(),
                    new Date(), loadOnlayer, null, rate, length);

                // 执行添加的操作
            Map<String, List<AddLinkDto>> map = addLinksToBasicNetwork(userDto, projectId, Collections.singletonList(link), false);
            if (map.get(failListKey).size() != 0)
                throw new BaseException(map.get(failListKey).get(0).getReason());
            return getOtnLinksList(userDto,projectId);
            }
    }

    @Override
    public Object getOtnLinksList(UserDto userDto, String projectId) throws BaseException {
        Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
        BasicNetWork basicNetWork = project.getBasicNetWork();
        List<IBasicNetWork.BasicLink> otnLinks = basicNetWork.getOtnLinks();
        List<OtnLinkDto> otnLinkDtos=new ArrayList<>();
        for (IBasicNetWork.BasicLink otnLink : otnLinks) {
            IBasicNetWork.OtnLink o = (IBasicNetWork.OtnLink) otnLink;
            List<Node> node = getNode(otnLink,project);
            OtnLinkDto otnLinkDto = new OtnLinkDto(o.getId(), o.getName(), o.getCode(), node.get(0), node.get(1), o.getLength(), o.getYear(), o.getSize(),o.getRateStr(), o.getLoadOnLayer());
            otnLinkDtos.add(otnLinkDto);
        }
        return otnLinkDtos;
    }

    @Override
    public Object updateOtnLink(UserDto userDto, String projectId, String linkId, String code, String linkName, int year, String loadOnlayer, String rate, long length) throws BaseException {
        userDto = userInfo.getCurrentOptUser();
        // 校验数据
        LocalVerify.verifyStringIsNotNull(code, linkId, linkName, loadOnlayer);
        synchronized (lock) {
            BasicNetWork.BasicLink link = new BasicNetWork.OtnLink(linkId, "OTN", code,
                    linkName, linkName, null,null, null,null, false, year, userDto.getUId(),
                    userDto.getUserName(),
                    new Date(), loadOnlayer, null, rate, length);
            // 执行添加的操作
            if (updateLinkToBasicNetWork(userDto, projectId, link)) {
                return getOtnLinksList(userDto, projectId);
            } else {
                throw new BaseException("更新otn链路失败");
            }
        }
    }

    @Override
    public Object deleteOtnLink(UserDto userDto, String projectId, String linkId) throws BaseException {
        LocalVerify.verifyString(linkId, "链路ID");
        LocalVerify.verifyStringIsNotNull(projectId);
        synchronized (lock) {
            if(removeLinkFromBasicNetwork(userDto, projectId,linkId, "OTN")){
                return getOtnLinksList(userDto,projectId);
            }else {
                throw new BaseException("删除otn链路失败");
            }
        }
    }

    @Override
    public Object addSdhLink(UserDto userDto, String projectId, String linkName, String code, String sourceId, String targetId, int year, String loadOnlayer, String rate, long length) throws BaseException {
        LocalVerify.verifyStringIsNotNull(code, linkName, targetId, sourceId, loadOnlayer);
        synchronized (lock) {
            // SDH 的 链路
            BasicNetWork.BasicLink link = new BasicNetWork.SdhLink(GenerateIDUtils.generateIdStr(),
                    "SDH", code, linkName, linkName, sourceId,null, targetId, null,false, year,
                    userDto.getUId(),
                    userDto.getUserName(), new Date(), rate, loadOnlayer, null, length);
            // 执行添加的操作
            Map<String, List<AddLinkDto>> map = addLinksToBasicNetwork(userDto, projectId, Collections.singletonList(link), false);
            if (map.get(failListKey).size() != 0)
                throw new BaseException(map.get(failListKey).get(0).getReason());
            return getSdhLinksList(userDto,projectId);
        }
    }

    @Override
    public Object getSdhLinksList(UserDto userDto, String projectId) throws BaseException {
        Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
        BasicNetWork basicNetWork = project.getBasicNetWork();
        List<IBasicNetWork.BasicLink> sdhLinks = basicNetWork.getSdhLinks();
        List<SdhLinkDto> sdhLinkDtos=new ArrayList<>();
        for (IBasicNetWork.BasicLink sdhLink : sdhLinks) {
            IBasicNetWork.SdhLink s = (IBasicNetWork.SdhLink) sdhLink;
            List<Node> node = getNode(sdhLink,project);

            SdhLinkDto sdhLinkDto = new SdhLinkDto(s.getId(), s.getName(), s.getCode(), node.get(0), node.get(1), s.getLength(), s.getYear(), s.getRateStr(), s.getLoadOnLayer());
          sdhLinkDtos.add(sdhLinkDto);
        }
        return sdhLinkDtos;
    }

    @Override
    public Object updateSdhLink(UserDto userDto, String projectId, String linkId, String code, String linkName, int year, String loadOnlayer, String rate, long length) throws BaseException {
        LocalVerify.verifyStringIsNotNull(code, linkName, rate, loadOnlayer);
        userDto = userInfo.getCurrentOptUser();
        synchronized (lock) {
            // SDH 的 链路
            BasicNetWork.BasicLink link = new BasicNetWork.SdhLink(linkId,
                    "SDH", code, linkName, linkName, null,null, null,null, false, year,
                   userDto.getUId(), userDto.getUserName(), new Date(),
                    rate, loadOnlayer, null, length);
            // 执行更新的操作
            // 执行添加的操作
            if (updateLinkToBasicNetWork(userDto, projectId, link)) {
                return getSdhLinksList(userDto, projectId);
            } else {
                throw new BaseException("更新sdh链路失败");
            }
        }
    }

    @Override
    public Object deleteSdhLink(UserDto userDto, String projectId, String linkId) throws BaseException {
        LocalVerify.verifyString(linkId, "链路ID");
        LocalVerify.verifyStringIsNotNull(projectId);
        synchronized (lock) {
            if(removeLinkFromBasicNetwork(userDto, projectId,linkId, "SDH")){
                return getWdmLinksList(userDto,projectId);
            }else {
                throw new BaseException("删除sdh链路失败");
            }
        }
    }

    private Map<String, List<AddLinkDto>> addLinksToBasicNetwork(UserDto userDto, String projectId, List<IBasicNetWork.BasicLink> links, boolean isOrigin) throws BaseException {
        Map<Class<?>, BasicNetWork.LayerEnum> clazzToIntegerMap = BasicNetWork.clazzToIntegerMap;
        userDto = userInfo.getCurrentOptUser();
        // 成功以及失败的list
        List<AddLinkDto> successList = new ArrayList<>();
        List<AddLinkDto> failList = new ArrayList<>();
        synchronized (lock) {
            Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
            BasicNetWork basicNetWork = project.getBasicNetWork();
            if (null != links && links.size() > 0) {
                // 循环处理链路的信息
                for (BasicNetWork.BasicLink link : links) {
                    try {
                        // 初始化 基本信息
                        if (!isOrigin) {
                            link.setCreateId(userDto.getUId());
                            link.setCreateName(userDto.getUserName());
                            link.setCreateTime(new Date());
                        }
                        // 设置ID的操作
                        // 进行修改成同一个的操作
                        if (null == link.getId() || "".equals(link.getId())) {
                            link.setId(GenerateIDUtils.generateIdStr());
                        }
                        LocalVerify.verifyString(link.getCode(), "【" + link.getName() + "】链路编码");
                        LocalVerify.verifyString(link.getName(), "链路名称");
                        LocalVerify.verifyString(link.getNodeHead(), "【" + link.getName() + "】链路头节点");
                        LocalVerify.verifyString(link.getNodeTail(), "【" + link.getName() + "】链路尾节点");
                        if (null == link.getYear()) throw new BaseException("【" + link.getName() + "】竣工年份必填");
                        try {
                            String nodeId = basicNetWork.getNodeId(link.getNodeHead());
                            link.setNodeHead(nodeId);
                            link.setNodeHeadName(basicNetWork.getNodeName(nodeId));
                        } catch (Exception e) {
                            throw new BaseException("【" + link.getName() + "】链路头节点不存在");
                        }
                        try {
                            String nodeId = basicNetWork.getNodeId(link.getNodeTail());
                            link.setNodeTail(nodeId);
                            link.setNodeTailName(basicNetWork.getNodeName(nodeId));
                        } catch (Exception e) {
                            throw new BaseException("【" + link.getName() + "】链路尾节点不存在");
                        }
                        List<Node> node = getNode(link, project);
                        link.setSourceNode(node.get(0));
                        link.setTargetNode(node.get(1));
                        // 校验基础的数据
                        if (preCheckLinkMsg(userDto, basicNetWork, link, clazzToIntegerMap.get(link.getClass()))) {
                            // 增加链路信息
                            link.setLabel(link.getName());
                            basicNetWork.addLink(link);
                            //成功的集合
                            successList.add(new AddLinkDto(link, "添加成功"));
                        }
                    } catch (Exception e) {
                        // 失败的集合
                        failList.add(new AddLinkDto(link, e.getMessage()));
                    }
                } // end for for (BasicNetWork.BasicLink link : links) {
            }
            // 返回操作
            Map<String, List<AddLinkDto>> res = new HashMap<>();
            res.put(successListKey, successList);
            res.put(failListKey, failList);
            // 更新网络信息
            this.updateProject(project);
            // return ok
            return res;
        }

    }

    private void updateProject(Project project) throws BaseException {
        boolean b = ProjectFactory.saveObjectDataToFile(project, project.getId(), ProjectFactory.storePath);
        if (!b) throw new BaseException("文件固化失败");
    }



        public boolean preCheckLinkMsg (@MParam("当前登陆的用户") UserDto userDto,
                @MParam("文件的项目") BasicNetWork netWork,
                BasicNetWork.BasicLink link,
                BasicNetWork.LayerEnum layer) throws BaseException {
            // 获取到基础的网络信息
            Set<String> nameSet = netWork.getBasicLinkNameSetByLayer(layer);
            if (null != nameSet && nameSet.contains(link.getName())) {
                throw new BaseException("【" + link.getName() + "】链路名称已经存在,请换一个名字再次尝试");
            }
            Map<String, BasicNetWork.BasicNode> nodeMap = netWork.getNodeMap();
            if (null != nodeMap && !nodeMap.containsKey(link.getNodeHead()))
                throw new BaseException("【" + link.getName() + "】 头节点不存在");
            if (null != nodeMap && !nodeMap.containsKey(link.getNodeTail()))
                throw new BaseException("【" + link.getName() + "】 尾节点不存在");
            // 校验其他的信息
            switch (layer) {
                case FIBER: {
                    BasicNetWork.FiberLink fiberLink = (BasicNetWork.FiberLink) link;
                    LocalVerify.verifyString(fiberLink.getAsfs(), "【" + link.getName() + "】敷设方式");
                    link.setLayer(BasicNetWork.LayerEnum.FIBER.getLayer());
                    // 设置长度的信息
                    fiberLink.setGlcd(link.getLength());
                    break;
                }
                case WDM: {
                    BasicNetWork.WdmLink wdmLink = (BasicNetWork.WdmLink) link;
                    if (null == wdmLink.getSize() || wdmLink.getSize() <= 0)
                        throw new BaseException("【" + link.getName() + "】配置波道数必填写并且大于0");
                    LocalVerify.verifyString(wdmLink.getRateStr(), "【" + link.getName() + "】线路速率");
                    // 设置子粒度的数目
                    wdmLink.setSize(wdmLink.getSize());
                    link.setLayer(BasicNetWork.LayerEnum.WDM.getLayer());
                    break;
                }
                case OTN: {
                    BasicNetWork.OtnLink otnLink = (BasicNetWork.OtnLink) link;
                    LocalVerify.verifyString(otnLink.getRateStr(), "【" + link.getName() + "】线路速率");
                    LocalVerify.verifyString(otnLink.getLoadOnLayer(), "承载层");
                    link.setLayer(BasicNetWork.LayerEnum.OTN.getLayer());
                    // 设置子粒度的数目
                    otnLink.setSize(BaseDataSupport.getOTNSlotNumByRateStr(otnLink.getRateStr()));
                    break;
                }
                case SDH: {
                    BasicNetWork.SdhLink sdhLink = (BasicNetWork.SdhLink) link;
                    LocalVerify.verifyString(sdhLink.getRateStr(), "【" + link.getName() + "】线路速率");
                    LocalVerify.verifyString(sdhLink.getLoadOnLayer(), "【" + link.getName() + "】承载层");
                    link.setLayer(BasicNetWork.LayerEnum.SDH.getLayer());
                    // 设置子粒度
                    sdhLink.setSize(BaseDataSupport.getSdhSlotNumByRateStr(sdhLink.getRateStr()));
                    break;
                }
            }
            return true; //return ok
        }


        static Double getRateByRateStr (String rateStr){
            if (null == rateStr || "".equals(rateStr)) return null;
            switch (rateStr) {
                case "155M":
                    return 0.125;
                case "622M":
                    return 0.5;
                case "GE":
                    return 1.0;
                case "2.5G":
                    return 2.5;
                case "10G":
                    return 10.0;
                case "40G":
                    return 40.0;
                case "100G":
                    return 100.0;
                default: {
                    return 0.0;
                }
            }
        }

    //用来获取承载的WDM链路的底层链路
    @Override
    public Object getLinksLoadMessageWdm(UserDto userDto, String projectId, String linkId) throws BaseException {
        synchronized (lock) {
            try {
                LocalVerify.verifyString(projectId, "projectId");
                LocalVerify.verifyString(linkId, "linkId");
                Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
                BasicNetWork netWork = project.getBasicNetWork();
                if (null != netWork) {
                    Map<String, BasicNetWork.BasicLink> basicLinkMapByLayer = netWork.getBasicLinkMapByLayer(BasicNetWork.LayerEnum.WDM);
                    IBasicNetWork.WdmLink wdmLink = (IBasicNetWork.WdmLink) basicLinkMapByLayer.get(linkId);
                    if (wdmLink != null) {
                        List<IBasicNetWork.WaveChannel> waveChannels = wdmLink.getWaveChannels();
                        int useWaveChannelNum = 0;
                        for (IBasicNetWork.WaveChannel waveChannel : waveChannels) {
                            if (waveChannel != null && waveChannel.getStatus().equals(LinkStatusString.WORK)) useWaveChannelNum++;
                        }
                        double util = Math.round((useWaveChannelNum * 1.0 / waveChannels.size()) * 100) / 100.0;//计算子粒度占用率
                        List<IBasicNetWork.BasicLink> baseLinks = basicLinkMapByLayer.get(linkId).getBaseLinks();//获取承载链路
                        return new LinkMsg(baseLinks, util);
                    }
                }
            }catch(Exception e){
                throw new BaseException(e.getMessage());
            }
            return  null;
        }
    }
//用来获取承载的OTN链路的底层链路
    @Override
    public Object getLinksLoadMessageOtn(UserDto userDto, String projectId, String linkId) throws BaseException {
        synchronized (lock) {
            try {
                LocalVerify.verifyString(projectId, "projectId");
                LocalVerify.verifyString(linkId, "linkId");
                Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
                BasicNetWork netWork = project.getBasicNetWork();
                if (null != netWork) {
                    Map<String, BasicNetWork.BasicLink> basicLinkMapByLayer = netWork.getBasicLinkMapByLayer(BasicNetWork.LayerEnum.OTN);
                    IBasicNetWork.OtnLink otnLink = (IBasicNetWork.OtnLink) basicLinkMapByLayer.get(linkId);
                    List<IBasicNetWork.OTU> otus = otnLink.getOtus();
                    int useOtuNum=0;
                    for (IBasicNetWork.OTU otu : otus) {
                        if(otu!=null&&otu.getStatus().equals(LinkStatusString.WORK)) useOtuNum++;
                    }
                    double util = Math.round((useOtuNum*1.0 / otus.size()) * 100) / 100.0;//计算子粒度占用率
                    List<IBasicNetWork.BasicLink> baseLinks = basicLinkMapByLayer.get(linkId).getBaseLinks();//获取承载链路
                    return  new LinkMsg(baseLinks, util);
                }
            }catch (Exception e){
                throw new BaseException(e.getMessage());
            }
            return null;
        }
    }

    @Override
    public Object getLinksLoadMessageSdh(UserDto userDto, String projectId, String linkId) throws BaseException {
        synchronized (lock) {
            try {
                LocalVerify.verifyString(projectId, "projectId");
                LocalVerify.verifyString(linkId, "linkId");
                Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
                BasicNetWork netWork = project.getBasicNetWork();
                if (null != netWork) {
                    Map<String, BasicNetWork.BasicLink> basicLinkMapByLayer = netWork.getBasicLinkMapByLayer(BasicNetWork.LayerEnum.SDH);
                    IBasicNetWork.SdhLink sdhLink = (IBasicNetWork.SdhLink) basicLinkMapByLayer.get(linkId);
                    List<IBasicNetWork.TimeSlot> timeSlots = sdhLink.getTimeSlots();
                    int useTimeSlotNum=0;
                    for (IBasicNetWork.TimeSlot timeSlot : timeSlots) {
                        if(timeSlot!=null&&timeSlot.getStatus().equals(LinkStatusString.WORK)) useTimeSlotNum++;
                    }
                    double util = Math.round((useTimeSlotNum*1.0/ timeSlots.size()) * 100) / 100.0;//计算子粒度占用率
                    List<IBasicNetWork.BasicLink> baseLinks = basicLinkMapByLayer.get(linkId).getBaseLinks();//获取承载链路
                    return new LinkMsg(baseLinks, util);
                }
            }catch (Exception e){
                throw new BaseException(e.getMessage());
            }
            return null;
        }
    }

    @Override
    public Boolean modRoute(UserDto userDto, String projectId, String linkId, String route) throws BaseException {
        synchronized (lock) {
            try {
                LocalVerify.verifyString(projectId, "projectId");
                LocalVerify.verifyString(linkId, "linkId");
                Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
                BasicNetWork netWork = project.getBasicNetWork();
                //建立list,存储lin
                ArrayList<String> linkIds = new ArrayList<>();
                String[] routes = route.split(",");
                linkIds.addAll(Arrays.asList(routes));
                List<IBasicNetWork.BasicLink> links=new ArrayList<>();
                Map<String, IBasicNetWork.BasicLink> fiberLinkHashMap = netWork.getFiberLinkHashMap();
                Map<String, IBasicNetWork.BasicLink> wdmLinkHashMap = netWork.getWdmLinkHashMap();
                Map<String, IBasicNetWork.BasicLink> otnLinkHashMap = netWork.getOtnLinkHashMap();
                Map<String, IBasicNetWork.BasicLink> sdhLinkHashMap = netWork.getSdhLinkHashMap();
                for (String id : linkIds) {
                    if(id!=null||!id.equals("")){
                    IBasicNetWork.BasicLink fiber= fiberLinkHashMap.get(id);
                    IBasicNetWork.BasicLink wdm = wdmLinkHashMap.get(id);
                    IBasicNetWork.BasicLink otn = otnLinkHashMap.get(id);
                    IBasicNetWork.BasicLink sdh = sdhLinkHashMap.get(id);
                    if(fiber!=null) links.add(fiber);
                    if(wdm!=null)links.add(wdm);
                    if(otn!=null)links.add(otn);
                    if(sdh!=null)links.add(sdh);
                    }
                }

                //若是wdm
                IBasicNetWork.BasicLink wdmLink = wdmLinkHashMap.get(linkId);
                if(wdmLink!=null){
                    if(!links.get(0).getNodeHeadName().equals(wdmLink.getNodeHeadName())||
                            !links.get(0).getNodeTailName().equals(wdmLink.getNodeTailName())) throw new BaseException("修改层间路由失败,请检查链路");
                    for (int i = 0; i < links.size()-1; i++) {
                        if(!links.get(i).getNodeTailName().equals(links.get(i+1).getNodeHeadName())) throw new BaseException("修改层间路由失败,请检查链路");
                    }
                    wdmLink.setLoadOnLinksIds(linkIds);
                    wdmLink.setBaseLinks(links);
                }

                //若是otn
                IBasicNetWork.BasicLink otnLink = otnLinkHashMap.get(linkId);
                if(otnLink!=null){
                    if(!links.get(0).getNodeHeadName().equals(otnLink.getNodeHeadName())||
                            !links.get(0).getNodeTailName().equals(otnLink.getNodeTailName())) throw new BaseException("修改层间路由失败,请检查链路");
                    for (int i = 0; i < links.size()-1; i++) {
                        if(!links.get(i).getNodeTailName().equals(links.get(i+1).getNodeHeadName())) throw new BaseException("修改层间路由失败,请检查链路");
                    }
                    otnLink.setLoadOnLinksIds(linkIds);
                    otnLink.setBaseLinks(links);

                }

                //若是sdh
                IBasicNetWork.BasicLink sdhLink = sdhLinkHashMap.get(linkId);
                if(sdhLink!=null){
                    if(!links.get(0).getNodeHeadName().equals(sdhLink.getNodeHeadName())||
                            !links.get(0).getNodeTailName().equals(sdhLink.getNodeTailName())) throw new BaseException("修改层间路由失败,请检查链路");
                    for (int i = 0; i < links.size()-1; i++) {
                        if(!links.get(i).getNodeTailName().equals(links.get(i+1).getNodeHeadName())) throw new BaseException("修改层间路由失败,请检查链路");
                    }
                    sdhLink.setLoadOnLinksIds(linkIds);
                    sdhLink.setBaseLinks(links);
                }

                return true;

            } catch (Exception e) {
                throw new BaseException(e.getMessage());
            }
        }
    }

    @Override
    public Object updateLoadOnLink(UserDto UserDto, String projectId,
                                   String linkId, String link1, String link2,
                                   String link3, String link4, String link5) throws BaseException {
        Project project = ProjectFactory.getObjectFromFile(projectId, ProjectFactory.storePath);
        BasicNetWork basicNetWork = project.getBasicNetWork();
        List<IBasicNetWork.BasicLink> wdmLinks = basicNetWork.getWdmLinks();
        List<IBasicNetWork.BasicLink> fiberLinks=basicNetWork.getFiberLinks();
        List<String> linksId =new ArrayList<>();
        List<IBasicNetWork.BasicLink> links=new ArrayList<>();
        if(!link1.equals("")||link1!=null){
            linksId.add(link1);
            for(IBasicNetWork.BasicLink baseLink:fiberLinks){
                if(baseLink.getId().equals(link1)){
                    links.add(baseLink);
                }
            }
        }
        if(!link2.equals("")||link2!=null){
            linksId.add(link2);
            for(IBasicNetWork.BasicLink baseLink:fiberLinks){
                if(baseLink.getId().equals(link2)){
                    links.add(baseLink);
                }
            }
        }
        if(!link3.equals("")||link3!=null){
            linksId.add(link3);
            for(IBasicNetWork.BasicLink baseLink:fiberLinks){
                if(baseLink.getId().equals(link3)){
                    links.add(baseLink);
                }
            }
        }
        if(!link4.equals("")||link4!=null){
            linksId.add(link4);
            for(IBasicNetWork.BasicLink baseLink:fiberLinks){
                if(baseLink.getId().equals(link4)){
                    links.add(baseLink);
                }
            }
        }
        if(!link5.equals("")||link5!=null){
            linksId.add(link5);
            for(IBasicNetWork.BasicLink baseLink:fiberLinks){
                if(baseLink.getId().equals(link5)){
                    links.add(baseLink);
                }
            }
        }

        for (IBasicNetWork.BasicLink wdmLink:wdmLinks) {
            if(wdmLink.getId().equals(linkId)){//找到了要修改的链路
                wdmLink.setLoadOnLinksIds(linksId);
                wdmLink.setBaseLinks(links);
                basicNetWork.updateLink(wdmLink);
                break;
            }
        }
        updateProject(project);
        return null;
    }

    @Data
        class AddLinkDto implements Serializable {
            private static final long serialVersionUID = 3177383509814403925L;
            private IBasicNetWork.BasicLink link;
            private String reason;

            public AddLinkDto(IBasicNetWork.BasicLink link, String reason) {
                this.link = link;
                this.reason = reason;
            }
        }

        @Data
        class LinkMsg implements Serializable {
            private static final long serialVersionUID = 3177383509814303925L;
            private List<IBasicNetWork.BasicLink> links;//承载链路list基本信息
            private Double util;//占用率

            public LinkMsg(List<IBasicNetWork.BasicLink> links, Double util) {
                this.links = links;
                this.util = util;
            }
        }


    }


